#include "Pch.h"
#include <ctype.h>
#include "Atom.h"
#include "Config.h"

AtomicInfo atomicInfo[] = {
	{"Actinium",		"Ac",	20,	'f',	 89,	227,		1.88f,	2.00f},
	{"Silver",			"Ag",	11,	'd',	 47,	107.868f,	1.59f,	1.72f},
	{"Aluminium",		"Al",	13,	'p',	 13,	 26.982f,	1.35f,	2.00f},
	{"Americium",		"Am",	20,	'f',	 95,	243,		1.51f,	2.00f},
	{"Argon",			"Ar",	18,	'p',	 18,	 39.948f,	1.51f,	1.88f},
	{"Arsenic",			"As",	15,	'p',	 33,	 74.922f,	1.21f,	1.85f},
	{"Astatine",		"At",	17,	'p',	 85,	210,		1.21f,	2.00f},
	{"Gold",			"Au",	11,	'd',	 79,	196.967f,	1.50f,	1.66f},
	{"Boron",			"B",	13,	'p',	  5,	 10.811f,	0.83f,	2.00f},
	{"Barium",			"Ba",	 2,	's',	 56,	137.327f,	1.34f,	2.00f},
	{"Beryllium",		"Be",	 2,	's',	  4,	  9.012f,	0.35f,	2.00f},
	{"Bohrium",			"Bh",	 7,	'd',	107,	264,		1.50f,	2.00f},
	{"Bismuth",			"Bi",	15,	'p',	 83,	208.980f,	1.54f,	2.00f},
	{"Berkelium",		"Bk",	20,	'f',	 97,	247,		1.54f,	2.00f},
	{"Bromine",			"Br",	17,	'p',	 35,	 79.904f,	1.21f,	1.85f},
	{"Carbon",			"C",	14,	'p',	  6,	 12.011f,	0.68f,	1.70f, ID_ATOM_COLOR_CARBON},
	{"Calcium",			"Ca",	 2,	's',	 20,	 40.078f,	0.99f,	2.00f},
	{"Cadmium",			"Cd",	12,	'd',	 48,	112.411f,	1.69f,	1.58f},
	{"Cerium",			"Ce",	19,	'f',	 58,	140.116f,	1.83f,	2.00f},
	{"Californium",		"Cf",	20,	'f',	 98,	251,		1.83f,	2.00f},
	{"Chlorine",		"Cl",	17,	'p',	 17,	 35.453f,	0.99f,	1.75f, ID_ATOM_COLOR_CHLORINE},
	{"Curium",			"Cm",	20,	'f',	 96,	247,		0.99f,	2.00f},
	{"Cobalt",			"Co",	 9,	'd',	 27,	 58.933f,	1.33f,	2.00f},
	{"Chromium",		"Cr",	 6,	'd',	 24,	 51.996f,	1.35f,	2.00f},
	{"Caesium",			"Cs",	 1,	's',	 55,	132.905f,	1.67f,	2.00f},
	{"Copper",			"Cu",	11,	'd',	 29,	 63.546f,	1.52f,	1.40f},
	{"Dubnium",			"Db",	 5,	'd',	105,	262,		1.50f,	2.00f},
	{"Darmstadtium",	"Ds",	10,	'd',	110,	271,		1.50f,	2.00f},
	{"Dysprosium",		"Dy",	19,	'f',	 66,	162.500f,	1.75f,	2.00f},
	{"Erbium",			"Er",	19,	'f',	 68,	167.260f,	1.73f,	2.00f},
	{"Einsteinium",		"Es",	20,	'f',	 99,	252,		1.50f,	2.00f},
	{"Europium",		"Eu",	19,	'f',	 63,	151.964f,	1.99f,	2.00f},
	{"Fluorine",		"F",	17,	'p',	  9,	 18.998f,	0.64f,	1.47f},
	{"Iron",			"Fe",	 8,	'd',	 26,	 55.845f,	1.34f,	2.00f},
	{"Fermium",			"Fm",	20,	'f',	100,	257,		1.50f,	2.00f},
	{"Francium",		"Fr",	 1,	's',	 87,	223,		1.50f,	2.00f},
	{"Gallium",			"Ga",	13,	'p',	 31,	 69.723f,	1.22f,	1.87f},
	{"Gadolinium",		"Gd",	19,	'f',	 64,	157.250f,	1.79f,	2.00f},
	{"Germanium",		"Ge",	14,	'p',	 32,	 72.610f,	1.17f,	2.00f},
	{"Hydrogen",		"H",	 1,	's',	  1,	  1.008f,	0.23f,	1.09f, ID_ATOM_COLOR_HYDROGEN},
	{"Helium",			"He",	18,	'p',	  2,	  4.003f,	1.50f,	1.40f},
	{"Hafnium",			"Hf",	 4,	'd',	 72,	178.490f,	1.57f,	2.00f},
	{"Mercury",			"Hg",	12,	'd',	 80,	200.590f,	1.70f,	1.55f},
	{"Holmium",			"Ho",	19,	'f',	 67,	164.930f,	1.74f,	2.00f},
	{"Hassium",			"Hs",	 8,	'd',	108,	269,		1.50f,	2.00f},
	{"Iodine",			"I",	17,	'p',	 53,	126.904f,	1.40f,	1.98f},
	{"Indium",			"In",	13,	'p',	 49,	114.818f,	1.63f,	1.93f},
	{"Iridium",			"Ir",	 9,	'd',	 77,	192.217f,	1.32f,	2.00f},
	{"Potassium",		"K",	 1,	's',	 19,	 39.098f,	1.33f,	2.75f},
	{"Krypton",			"Kr",	18,	'p',	 36,	 83.800f,	1.50f,	2.02f},
	{"Lanthanum",		"La",	19,	'f',	 57,	138.906f,	1.87f,	2.00f},
	{"Lithium",			"Li",	 1,	's',	  3,	  6.941f,	0.68f,	1.82f},
	{"Lawrencium",		"Lr",	 3,	'd',	103,	262,		1.50f,	2.00f},
	{"Lawrencium",		"Lw",	 3,	'd',	103,	262,		1.50f,	2.00f},
	{"Lutetium",		"Lu",	 3,	'd',	 71,	174.967f,	1.72f,	2.00f},
	{"Mendelevium",		"Md",	20,	'f',	101,	258,		1.50f,	2.00f},
	{"Magnesium",		"Mg",	 2,	's',	 12,	 24.305f,	1.10f,	1.73f},
	{"Manganese",		"Mn",	 7,	'd',	 25,	 54.938f,	1.35f,	2.00f},
	{"Molybdenum",		"Mo",	 6,	'd',	 42,	 95.940f,	1.47f,	2.00f},
	{"Meitnerium",		"Mt",	 9,	'd',	109,	268,		1.50f,	2.00f},
	{"Nitrogen",		"N",	15,	'p',	  7,	 14.007f,	0.68f,	1.55f, ID_ATOM_COLOR_NITROGEN},
	{"Sodium",			"Na",	 1,	's',	 11,	 22.991f,	0.97f,	2.27f},
	{"Niobium",			"Nb",	 5,	'd',	 41,	 92.906f,	1.48f,	2.00f},
	{"Neodymium",		"Nd",	19,	'f',	 60,	144.240f,	1.81f,	2.00f},
	{"Neon",			"Ne",	18,	'p',	 10,	 20.180f,	1.50f,	1.54f},
	{"Nickel",			"Ni",	10,	'd',	 28,	 58.693f,	1.50f,	1.63f},
	{"Nobelium",		"No",	20,	'f',	102,	259,		1.50f,	2.00f},
	{"Neptunium",		"Np",	20,	'f',	 93,	237,		1.55f,	2.00f},
	{"Oxygen",			"O",	16,	'p',	  8,	 15.999f,	0.68f,	1.52f, ID_ATOM_COLOR_OXYGEN},
	{"Osmium",			"Os",	 8,	'd',	 76,	190.230f,	1.37f,	2.00f},
	{"Phosphorus",		"P",	15,	'p',	 15,	 30.974f,	1.05f,	1.80f, ID_ATOM_COLOR_PHOSPHORUS},
	{"Protactinium",	"Pa",	20,	'f',	 91,	231.036f,	1.61f,	2.00f},
	{"Lead",			"Pb",	14,	'p',	 82,	207.200f,	1.54f,	2.02f},
	{"Palladium",		"Pd",	10,	'd',	 46,	106.420f,	1.50f,	1.63f},
	{"Promethium",		"Pm",	19,	'f',	 61,	145,		1.80f,	2.00f},
	{"Polonium",		"Po",	16,	'p',	 84,	210,		1.68f,	2.00f},
	{"Praseodymium",	"Pr",	19,	'f',	 59,	140.908f,	1.82f,	2.00f},
	{"Platinum",		"Pt",	10,	'd',	 78,	195.078f,	1.50f,	1.72f},
	{"Plutonium",		"Pu",	20,	'f',	 94,	244,		1.53f,	2.00f},
	{"Radium",			"Ra",	 2,	's',	 88,	226,		1.90f,	2.00f},
	{"Rubidium",		"Rb",	 1,	's',	 37,	 85.468f,	1.47f,	2.00f},
	{"Rhenium",			"Re",	 7,	'd',	 75,	186.207f,	1.35f,	2.00f},
	{"Rutherfordium",	"Rf",	 4,	'd',	104,	261,		1.50f,	2.00f},
	{"Rhodium",			"Rh",	 9,	'd',	 45,	102.906f,	1.45f,	2.00f},
	{"Radon",			"Rn",	18,	'p',	 86,	222,		1.50f,	2.00f},
	{"Ruthenium",		"Ru",	 8,	'd',	 44,	101.070f,	1.40f,	2.00f},
	{"Sulphur",			"S",	16,	'p',	 16,	 32.066f,	1.02f,	1.80f, ID_ATOM_COLOR_SULPHUR},
	{"Antimony",		"Sb",	15,	'p',	 51,	121.760f,	1.46f,	2.00f},
	{"Scandium",		"Sc",	 3,	'd',	 21,	 44.956f,	1.44f,	2.00f},
	{"Selenium",		"Se",	16,	'p',	 34,	 78.960f,	1.22f,	1.90f},
	{"Seaborgium",		"Sg",	 6,	'd',	106,	266,		1.50f,	2.00f},
	{"Silicon",			"Si",	14,	'p',	 14,	 28.086f,	1.20f,	2.10f},
	{"Samarium",		"Sm",	19,	'f',	 62,	150.360f,	1.80f,	2.00f},
	{"Tin", 			"Sn",	14,	'p',	 50,	118.710f,	1.46f,	2.17f},
	{"Strontium",		"Sr",	 2,	's',	 38,	 87.620f,	1.12f,	2.00f},
	{"Tantalum",		"Ta",	 5,	'd',	 73,	180.948f,	1.43f,	2.00f},
	{"Terbium",			"Tb",	19,	'f',	 65,	158.925f,	1.76f,	2.00f},
	{"Technetium",		"Tc",	 7,	'd',	 43,	 98,		1.35f,	2.00f},
	{"Tellurium",		"Te",	16,	'p',	 52,	127.600f,	1.47f,	2.06f},
	{"Thorium",			"Th",	20,	'f',	 90,	232.038f,	1.79f,	2.00f},
	{"Titanium",		"Ti",	 4,	'd',	 22,	 47.867f,	1.47f,	2.00f},
	{"Thallium",		"Tl",	13,	'p',	 81,	204.383f,	1.55f,	1.96f},
	{"Thulium",			"Tm",	19,	'f',	 69,	168.934f,	1.72f,	2.00f},
	{"Uranium",			"U",	20,	'f',	 92,	238.029f,	1.58f,	1.86f},
	{"Vanadium",		"V",	 5,	'd',	 23,	 50.942f,	1.33f,	2.00f},
	{"Tungsten",		"W",	 6,	'd',	 74,	183.840f,	1.37f,	2.00f},
	{"Xenon",			"Xe",	18,	'p',	 54,	131.290f,	1.50f,	2.16f},
	{"Yttrium",			"Y",	 3,	'd',	 39,	 88.906f,	1.78f,	2.00f},
	{"Ytterbium",		"Yb",	19,	'f',	 70,	173.040f,	1.94f,	2.00f},
	{"Zinc",			"Zn",	12,	'd',	 30,	 65.390f,	1.45f,	1.39f},
	{"Zirconium",		"Zr",	 4,	'd',	 40,	 91.224f,	1.56f,	2.00f},
};

// Returns value from 0 to 26*27.  27 needed because of single character names.
// Works for single character symbols followed by both space and null and
// preceeded by a space (And two character symbols as well).
unsigned int AtomicSymbolToInt(const char *symbol) {
	unsigned int res;
	if (symbol[0] == ' ') {
		unsigned int v = toupper(symbol[1]) - 'A';
		if (v > 26) return 0;
		return v*27;
	}
	unsigned int v = toupper(symbol[0]) - 'A';
	if (v > 26) {
		return 0;
	}
	res = v * 27;
	v = toupper(symbol[1]) - 'A';
	if (v < 26) {
		res += v+1;
	}
	return res;
}

int SymbolEquals(char *symbol1, char *symbol2) {
	int id1 = AtomicSymbolToInt(symbol1);
	int id2 = AtomicSymbolToInt(symbol2);
	return id1 == id2 && id1;
}

AtomicInfo *atomicInfoTable[26*27] = {0};

void InitAtomicInfo() {
	// Hydrogen.
	if (!atomicInfoTable[26*('H'-'A')]) {
		for (int i=0; i<sizeof(atomicInfo)/sizeof(AtomicInfo); i++) {
			int intId = AtomicSymbolToInt(atomicInfo[i].symbol);
			atomicInfoTable[intId] = &atomicInfo[i];
		}
	}
}

// More optimization than is really needed...
AtomicInfo *GetAtomicInfo(char *symbol) {
	int intId = AtomicSymbolToInt(symbol);
	return atomicInfoTable[intId];
};

Color GetAtomicColor(char *id) {
	AtomicInfo *info = GetAtomicInfo(id);
	int index = 0;
	if (info) index = info->colorIndex;
	return config->atomicColors[index];
}

Color GetAtomicColor(int index) {
	return config->atomicColors[index];
}

Color GetAtomicColorByAtomIndex(int index) {
	return config->atomicColors[atomicInfoTable[index]->colorIndex];
}
